<template>
	<transition name="image-viewer" appear>
		<div class="full-image-viewer" v-if="show" @click="handleMaskClick" @keydown.esc="close" tabindex="0"
			ref="viewerRef">
			<!-- 背景遮罩 -->
			<div class="mask" @click="close"></div>

			<!-- 工具栏 -->
			<div class="toolbar">
				<div class="toolbar-left">
					<span class="image-info">{{ currentIndex + 1 }} / {{ images.length }}</span>
					<span class="image-name" v-if="currentImage.name">{{ currentImage.name }}</span>
				</div>
				<div class="toolbar-right">
					<button class="tool-btn" @click="zoomOut" :disabled="scale <= 0.1" title="缩小">
						<i class="fas fa-search-minus"></i>
					</button>
					<span class="zoom-info">{{ Math.round(scale * 100) }}%</span>
					<button class="tool-btn" @click="zoomIn" :disabled="scale >= 5" title="放大">
						<i class="fas fa-search-plus"></i>
					</button>
					<button class="tool-btn" @click="resetZoom" title="重置缩放">
						<i class="fas fa-expand-arrows-alt"></i>
					</button>
					<button class="tool-btn" @click="rotateLeft" title="逆时针旋转">
						<i class="fas fa-undo"></i>
					</button>
					<button class="tool-btn" @click="rotateRight" title="顺时针旋转">
						<i class="fas fa-redo"></i>
					</button>
					<button class="tool-btn" @click="downloadImage" title="下载图片">
						<i class="fas fa-download"></i>
					</button>
					<button class="tool-btn close-btn" @click="close" title="关闭">
						<i class="fas fa-times"></i>
					</button>
				</div>
			</div>

			<!-- 图片容器 -->
			<div class="image-container" ref="containerRef">
				<div class="image-wrapper" :style="imageStyle" @mousedown="startDrag" @wheel="handleWheel">
					<img :src="currentImage.url" :alt="currentImage.name || '图片预览'" @load="handleImageLoad"
						@error="handleImageError" @dragstart.prevent ref="imageRef" />

					<!-- 加载状态 -->
					<div class="loading" v-if="loading">
						<i class="fas fa-spinner fa-spin"></i>
						<span>加载中...</span>
					</div>

					<!-- 错误状态 -->
					<div class="error" v-if="error">
						<i class="fas fa-exclamation-triangle"></i>
						<span>图片加载失败</span>
					</div>
				</div>
			</div>

			<!-- 导航按钮 -->
			<button class="nav-btn prev-btn" v-if="images.length > 1" @click="prevImage" :disabled="currentIndex === 0"
				title="上一张">
				<i class="fas fa-chevron-left"></i>
			</button>
			<button class="nav-btn next-btn" v-if="images.length > 1" @click="nextImage"
				:disabled="currentIndex === images.length - 1" title="下一张">
				<i class="fas fa-chevron-right"></i>
			</button>

			<!-- 缩略图列表 -->
			<div class="thumbnail-list" v-if="images.length > 1">
				<div class="thumbnail-item" v-for="(image, index) in images" :key="index"
					:class="{ active: index === currentIndex }" @click="setCurrentImage(index)">
					<img :src="image.url" :alt="image.name || `图片${index + 1}`" />
				</div>
			</div>
		</div>
	</transition>
</template>

<script>
/**
 * 全屏图片查看器组件
 * 功能特性：
 * - 支持单张或多张图片预览
 * - 缩放、旋转、拖拽操作
 * - 键盘快捷键支持
 * - 缩略图导航
 * - 图片下载功能
 * - 深色模式适配
 * - 响应式设计
 */
export default {
	name: "FullImage",
	data() {
		return {
			show: false, // 显示状态
			images: [], // 图片列表，支持多张图片
			currentIndex: 0, // 当前显示的图片索引
			scale: 1, // 图片缩放比例 (0.1-5倍)
			rotation: 0, // 图片旋转角度
			translateX: 0, // 图片X轴偏移量
			translateY: 0, // 图片Y轴偏移量
			loading: false, // 图片加载状态
			error: false, // 图片加载错误状态
			isDragging: false, // 是否正在拖拽图片
			dragStartX: 0, // 拖拽开始时的鼠标X坐标
			dragStartY: 0, // 拖拽开始时的鼠标Y坐标
			dragStartTranslateX: 0, // 拖拽开始时的图片X偏移
			dragStartTranslateY: 0, // 拖拽开始时的图片Y偏移
		}
	},
	computed: {
		// 当前图片对象
		currentImage() {
			return this.images[this.currentIndex] || { url: '', name: '' };
		},
		// 图片样式
		imageStyle() {
			return {
				transform: `translate(${this.translateX}px, ${this.translateY}px) scale(${this.scale}) rotate(${this.rotation}deg)`,
				transition: this.isDragging ? 'none' : 'transform 0.3s ease',
				cursor: this.isDragging ? 'grabbing' : (this.scale > 1 ? 'grab' : 'default')
			};
		}
	},
	mounted() {
		// 添加键盘事件监听
		document.addEventListener('keydown', this.handleKeydown);
		// 添加鼠标事件监听
		document.addEventListener('mousemove', this.handleDrag);
		document.addEventListener('mouseup', this.stopDrag);

		// 手动将组件挂载到 body，模拟 teleport 效果
		this.$nextTick(() => {
			if (this.$el && this.$el.parentNode !== document.body) {
				document.body.appendChild(this.$el);
			}
		});
	},
	beforeDestroy() {
		// 移除事件监听
		document.removeEventListener('keydown', this.handleKeydown);
		document.removeEventListener('mousemove', this.handleDrag);
		document.removeEventListener('mouseup', this.stopDrag);

		// 从 body 中移除元素
		if (this.$el && this.$el.parentNode === document.body) {
			document.body.removeChild(this.$el);
		}
	},
	methods: {
		/**
		 * 打开图片查看器
		 * @param {string|Array} images - 图片URL或图片数组
		 * @param {number} index - 初始显示的图片索引
		 */
		open(images, index = 0) {
			// 处理单张图片
			if (typeof images === 'string') {
				this.images = [{ url: images, name: '' }];
			}
			// 处理图片数组
			else if (Array.isArray(images)) {
				this.images = images.map(img => {
					if (typeof img === 'string') {
						return { url: img, name: '' };
					}
					return { url: img.url || img.src || img, name: img.name || img.title || '' };
				});
			} else {
				this.images = [{ url: images.url || images.src || images, name: images.name || images.title || '' }];
			}

			this.currentIndex = Math.max(0, Math.min(index, this.images.length - 1));
			this.show = true;
			this.resetTransform();

			// 聚焦到查看器以支持键盘操作
			this.$nextTick(() => {
				if (this.$refs.viewerRef) {
					this.$refs.viewerRef.focus();
				}
			});
		},

		/**
		 * 关闭图片查看器
		 */
		close() {
			this.show = false;
			this.resetTransform();
			this.loading = false;
			this.error = false;
		},

		/**
		 * 重置变换状态
		 */
		resetTransform() {
			this.scale = 1;
			this.rotation = 0;
			this.translateX = 0;
			this.translateY = 0;
			this.isDragging = false;
		},

		/**
		 * 处理遮罩点击
		 */
		handleMaskClick(event) {
			// 只有点击遮罩时才关闭
			if (event.target.classList.contains('mask')) {
				this.close();
			}
		},

		/**
		 * 放大
		 */
		zoomIn() {
			if (this.scale < 5) {
				this.scale = Math.min(5, this.scale + 0.25);
			}
		},

		/**
		 * 缩小
		 */
		zoomOut() {
			if (this.scale > 0.1) {
				this.scale = Math.max(0.1, this.scale - 0.25);
			}
		},

		/**
		 * 重置缩放
		 */
		resetZoom() {
			this.scale = 1;
			this.translateX = 0;
			this.translateY = 0;
		},

		/**
		 * 向左旋转
		 */
		rotateLeft() {
			this.rotation -= 90;
		},

		/**
		 * 向右旋转
		 */
		rotateRight() {
			this.rotation += 90;
		},

		/**
		 * 上一张图片
		 */
		prevImage() {
			if (this.currentIndex > 0) {
				this.currentIndex--;
				this.resetTransform();
			}
		},

		/**
		 * 下一张图片
		 */
		nextImage() {
			if (this.currentIndex < this.images.length - 1) {
				this.currentIndex++;
				this.resetTransform();
			}
		},

		/**
		 * 设置当前图片
		 */
		setCurrentImage(index) {
			if (index >= 0 && index < this.images.length) {
				this.currentIndex = index;
				this.resetTransform();
			}
		},

		/**
		 * 下载图片
		 */
		async downloadImage() {
			try {
				const response = await fetch(this.currentImage.url);
				const blob = await response.blob();
				const url = window.URL.createObjectURL(blob);
				const link = document.createElement('a');
				link.href = url;
				link.download = this.currentImage.name || `image_${Date.now()}.jpg`;
				document.body.appendChild(link);
				link.click();
				document.body.removeChild(link);
				window.URL.revokeObjectURL(url);
			} catch (error) {
				console.error('下载图片失败:', error);
				this.$message?.error('下载图片失败');
			}
		},

		/**
		 * 处理图片加载
		 */
		handleImageLoad() {
			this.loading = false;
			this.error = false;
		},

		/**
		 * 处理图片加载错误
		 */
		handleImageError() {
			this.loading = false;
			this.error = true;
		},

		/**
		 * 处理鼠标滚轮缩放
		 */
		handleWheel(event) {
			event.preventDefault();
			const delta = event.deltaY > 0 ? -0.1 : 0.1;
			const newScale = Math.max(0.1, Math.min(5, this.scale + delta));
			this.scale = newScale;
		},

		/**
		 * 开始拖拽
		 */
		startDrag(event) {
			if (this.scale <= 1) return; // 只有放大时才能拖拽

			event.preventDefault();
			this.isDragging = true;
			this.dragStartX = event.clientX;
			this.dragStartY = event.clientY;
			this.dragStartTranslateX = this.translateX;
			this.dragStartTranslateY = this.translateY;
		},

		/**
		 * 处理拖拽
		 */
		handleDrag(event) {
			if (!this.isDragging) return;

			const deltaX = event.clientX - this.dragStartX;
			const deltaY = event.clientY - this.dragStartY;

			this.translateX = this.dragStartTranslateX + deltaX;
			this.translateY = this.dragStartTranslateY + deltaY;
		},

		/**
		 * 停止拖拽
		 */
		stopDrag() {
			this.isDragging = false;
		},

		/**
		 * 处理键盘事件
		 */
		handleKeydown(event) {
			if (!this.show) return;

			switch (event.key) {
				case 'Escape':
					this.close();
					break;
				case 'ArrowLeft':
					this.prevImage();
					break;
				case 'ArrowRight':
					this.nextImage();
					break;
				case '+':
				case '=':
					this.zoomIn();
					break;
				case '-':
					this.zoomOut();
					break;
				case '0':
					this.resetZoom();
					break;
				case 'r':
				case 'R':
					this.rotateRight();
					break;
			}
		}
	}
}
</script>

<style lang="scss" scoped>
@use "@/styles/variables.scss" as *;

// 动画效果
.image-viewer-enter-active,
.image-viewer-leave-active {
	transition: all 0.3s ease;
}

.image-viewer-enter-from,
.image-viewer-leave-to {
	opacity: 0;
	transform: scale(0.8);
}

.full-image-viewer {
	position: fixed;
	top: 0;
	left: 0;
	width: 100vw;
	height: 100vh;
	z-index: 9999;
	display: flex;
	flex-direction: column;
	background: rgba(0, 0, 0, 0.55);
	backdrop-filter: blur(2px);
	user-select: none;
	outline: none;

	// 背景遮罩
	.mask {
		position: absolute;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		background: transparent;
		cursor: pointer;
	}

	// 工具栏
	.toolbar {
		position: relative;
		z-index: 10;
		display: flex;
		justify-content: space-between;
		align-items: center;
		padding: 16px 24px;
		background: rgba(0, 0, 0, 0.2);
		backdrop-filter: blur(2px);
		border-bottom: 1px solid rgba(255, 255, 255, 0.1);

		.toolbar-left {
			display: flex;
			align-items: center;
			gap: 16px;
			color: white;

			.image-info {
				font-size: 14px;
				font-weight: 500;
				opacity: 0.9;
			}

			.image-name {
				font-size: 14px;
				opacity: 0.7;
				max-width: 300px;
				overflow: hidden;
				text-overflow: ellipsis;
				white-space: nowrap;
			}
		}

		.toolbar-right {
			display: flex;
			align-items: center;
			gap: 8px;

			.zoom-info {
				color: white;
				font-size: 14px;
				font-weight: 500;
				min-width: 50px;
				text-align: center;
				opacity: 0.9;
			}

			.tool-btn {
				display: flex;
				align-items: center;
				justify-content: center;
				width: 40px;
				height: 40px;
				background: rgba(255, 255, 255, 0.1);
				border: 1px solid rgba(255, 255, 255, 0.2);
				border-radius: 8px;
				color: white;
				cursor: pointer;
				transition: all 0.2s ease;
				font-size: 16px;

				&:hover:not(:disabled) {
					background: rgba(255, 255, 255, 0.2);
					border-color: rgba(255, 255, 255, 0.3);
					transform: translateY(-1px);
				}

				&:active:not(:disabled) {
					transform: translateY(0);
				}

				&:disabled {
					opacity: 0.4;
					cursor: not-allowed;
				}

				&.close-btn {
					background: rgba(239, 68, 68, 0.2);
					border-color: rgba(239, 68, 68, 0.3);

					&:hover {
						background: rgba(239, 68, 68, 0.3);
						border-color: rgba(239, 68, 68, 0.4);
					}
				}
			}
		}
	}

	// 图片容器
	.image-container {
		position: relative;
		flex: 1;
		display: flex;
		align-items: center;
		justify-content: center;
		overflow: hidden;
		z-index: 1;

		.image-wrapper {
			position: relative;
			display: flex;
			align-items: center;
			justify-content: center;
			transform-origin: center;

			img {
				max-width: 90vw;
				max-height: 80vh;
				object-fit: contain;
				border-radius: 8px;
				box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
			}

			.loading,
			.error {
				position: absolute;
				top: 50%;
				left: 50%;
				transform: translate(-50%, -50%);
				display: flex;
				flex-direction: column;
				align-items: center;
				gap: 12px;
				color: white;
				font-size: 16px;

				i {
					font-size: 32px;
					opacity: 0.8;
				}

				span {
					opacity: 0.9;
				}
			}

			.loading i {
				animation: spin 1s linear infinite;
			}

			.error {
				color: #ef4444;
			}
		}
	}

	// 导航按钮
	.nav-btn {
		position: absolute;
		top: 50%;
		transform: translateY(-50%);
		z-index: 10;
		display: flex;
		align-items: center;
		justify-content: center;
		width: 60px;
		height: 60px;
		background: rgba(0, 0, 0, 0.5);
		border: 1px solid rgba(255, 255, 255, 0.2);
		border-radius: 50%;
		color: white;
		cursor: pointer;
		transition: all 0.3s ease;
		font-size: 20px;

		&:hover:not(:disabled) {
			background: rgba(0, 0, 0, 0.7);
			border-color: rgba(255, 255, 255, 0.3);
			transform: translateY(-50%) scale(1.1);
		}

		&:disabled {
			opacity: 0.3;
			cursor: not-allowed;
		}

		&.prev-btn {
			left: 24px;
		}

		&.next-btn {
			right: 24px;
		}
	}

	// 缩略图列表
	.thumbnail-list {
		position: absolute;
		bottom: 24px;
		left: 50%;
		transform: translateX(-50%);
		z-index: 10;
		display: flex;
		gap: 8px;
		padding: 12px 16px;
		background: rgba(0, 0, 0, 0.2);
		backdrop-filter: blur(2px);
		border-radius: 12px;
		border: 1px solid rgba(255, 255, 255, 0.1);
		max-width: 80vw;
		overflow-x: auto;

		// 隐藏滚动条
		&::-webkit-scrollbar {
			display: none;
		}

		.thumbnail-item {
			flex-shrink: 0;
			width: 60px;
			height: 60px;
			border-radius: 8px;
			overflow: hidden;
			cursor: pointer;
			transition: all 0.2s ease;
			border: 2px solid transparent;

			&:hover {
				transform: scale(1.1);
				border-color: rgba(255, 255, 255, 0.3);
			}

			&.active {
				border-color: $primary;
				transform: scale(1.05);
			}

			img {
				width: 100%;
				height: 100%;
				object-fit: cover;
			}
		}
	}
}

// 深色模式适配
:root[data-theme='dark'] {
	.full-image-viewer {
		background: rgba(0, 0, 0, 0.8);

		.toolbar {
			background: rgba(0, 0, 0, 0.8);
			border-bottom-color: rgba(255, 255, 255, 0.05);
		}

		.thumbnail-list {
			background: rgba(0, 0, 0, 0.8);
			border-color: rgba(255, 255, 255, 0.05);
		}
	}
}

// 动画定义
@keyframes spin {
	from {
		transform: rotate(0deg);
	}

	to {
		transform: rotate(360deg);
	}
}

// 响应式设计
@media (max-width: 768px) {
	.full-image-viewer {
		.toolbar {
			padding: 12px 16px;
			flex-wrap: wrap;
			gap: 8px;

			.toolbar-left {
				order: 2;
				width: 100%;
				justify-content: center;

				.image-name {
					max-width: 200px;
				}
			}

			.toolbar-right {
				order: 1;
				width: 100%;
				justify-content: center;

				.tool-btn {
					width: 36px;
					height: 36px;
					font-size: 14px;
				}

				.zoom-info {
					font-size: 12px;
					min-width: 40px;
				}
			}
		}

		.nav-btn {
			width: 50px;
			height: 50px;
			font-size: 18px;

			&.prev-btn {
				left: 16px;
			}

			&.next-btn {
				right: 16px;
			}
		}

		.thumbnail-list {
			bottom: 16px;
			padding: 8px 12px;
			max-width: 90vw;

			.thumbnail-item {
				width: 50px;
				height: 50px;
			}
		}

		.image-container .image-wrapper img {
			max-width: 95vw;
			max-height: 70vh;
		}
	}
}
</style>
